Add GdkRGBA struct to supersede GdkColor
authorCarlos Garnacho <carlosg@gnome.org>
Thu, 21 Oct 2010 13:23:48 +0000 (15:23 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Fri, 22 Oct 2010 18:14:56 +0000 (20:14 +0200)
GdkRGBA is a boxed struct similar to GdkColor, with the difference
that it stores alpha information as well, and colors are stored in
[0..1] doubles, in the cairo spirit.

gdk_cairo_set_source_rgba() has been also added to allow easier handling
of this new type.

docs/reference/gdk/gdk-docs.sgml
docs/reference/gdk/gdk3-sections.txt
gdk/Makefile.am
gdk/gdkcairo.c
gdk/gdkcairo.h
gdk/gdkrgba.c [new file with mode: 0644]
gdk/gdkrgba.h [new file with mode: 0644]
gdk/gdktypes.h

index 4a14ce950f10859e8977d6f8c5a16fd3475699fe..a4f4d39123139274d29a2cfa1329aefcf948d4f4 100644 (file)
@@ -24,6 +24,7 @@
     <xi:include href="xml/regions.xml" />
     <xi:include href="xml/drawing.xml" />
     <xi:include href="xml/colors.xml" />
+    <xi:include href="xml/rgba_colors.xml" />
     <xi:include href="xml/visuals.xml" />
     <xi:include href="xml/cursors.xml" />
     <xi:include href="xml/windows.xml" />
index 3536055c379ca446bf3363effc72ffefc4461453..db074de00afab3c25c0ab43908852a502e59618f 100644 (file)
@@ -259,6 +259,21 @@ GDK_TYPE_COLOR
 
 </SECTION>
 
+<SECTION>
+<TITLE>RGBA Colors</TITLE>
+<FILE>rgba_colors</FILE>
+GdkRGBA
+gdk_rgba_copy
+gdk_rgba_free
+gdk_rgba_parse
+gdk_rgba_equal
+gdk_rgba_hash
+gdk_rgba_to_string
+
+<SUBSECTION Standard>
+GDK_TYPE_RGBA
+</SECTION>
+
 <SECTION>
 <TITLE>Drawing Primitives</TITLE>
 <FILE>drawing</FILE>
@@ -595,6 +610,7 @@ gdk_window_create_similar_surface
 gdk_cairo_create
 gdk_cairo_get_clip_rectangle
 gdk_cairo_set_source_color
+gdk_cairo_set_source_rgba
 gdk_cairo_set_source_pixbuf
 gdk_cairo_set_source_window
 gdk_cairo_rectangle
index de4957592bab7e268c74759aaebe7c49afe6d618..bc0f00245b6ebca51af5698e9fd9e40236fd188c 100644 (file)
@@ -91,6 +91,7 @@ gdk_public_h_sources =                                \
        gdkprivate.h                            \
        gdkproperty.h                           \
        gdkrectangle.h                          \
+       gdkrgba.h                               \
        gdkscreen.h                             \
        gdkselection.h                          \
        gdkspawn.h                              \
@@ -130,6 +131,7 @@ gdk_c_sources =                 \
        gdkpango.c              \
        gdkpixbuf-drawable.c    \
        gdkrectangle.c          \
+       gdkrgba.c               \
        gdkscreen.c             \
        gdkselection.c          \
        gdkvisual.c             \
index 5e711b6ab659502ccf0f91333f9084fabffe6900..197e2c41e928b7cd48d925a8580a5c8c8278d728 100644 (file)
@@ -167,6 +167,20 @@ gdk_cairo_set_source_color (cairo_t        *cr,
                        color->blue / 65535.);
 }
 
+void
+gdk_cairo_set_source_rgba (cairo_t       *cr,
+                           const GdkRGBA *rgba)
+{
+  g_return_if_fail (cr != NULL);
+  g_return_if_fail (rgba != NULL);
+
+  cairo_set_source_rgba (cr,
+                         rgba->red,
+                         rgba->green,
+                         rgba->blue,
+                         rgba->alpha);
+}
+
 /**
  * gdk_cairo_rectangle:
  * @cr: a #cairo_t
index 6da20007c4f1b293305f336b06214b163c8a469a..b9b45e5f08be28875eb1c05008f2fe6add4648b8 100644 (file)
@@ -25,6 +25,7 @@
 #define __GDK_CAIRO_H__
 
 #include <gdk/gdkcolor.h>
+#include <gdk/gdkrgba.h>
 #include <gdk/gdkpixbuf.h>
 #include <pango/pangocairo.h>
 
@@ -38,6 +39,8 @@ gboolean gdk_cairo_get_clip_rectangle(cairo_t            *cr,
 
 void     gdk_cairo_set_source_color  (cairo_t            *cr,
                                       const GdkColor     *color);
+void     gdk_cairo_set_source_rgba   (cairo_t            *cr,
+                                      const GdkRGBA      *rgba);
 void     gdk_cairo_set_source_pixbuf (cairo_t            *cr,
                                       const GdkPixbuf    *pixbuf,
                                       double              pixbuf_x,
diff --git a/gdk/gdkrgba.c b/gdk/gdkrgba.c
new file mode 100644 (file)
index 0000000..68f602d
--- /dev/null
@@ -0,0 +1,277 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+#include "gdkrgba.h"
+#include <string.h>
+
+/**
+ * SECTION:rgba_colors
+ * @Short_description: RGBA colors
+ * @Title: RGBA Colors
+ */
+
+G_DEFINE_BOXED_TYPE (GdkRGBA, gdk_rgba,
+                     gdk_rgba_copy, gdk_rgba_free)
+
+/**
+ * gdk_rgba_copy:
+ * @rgba: a #GdkRGBA
+ *
+ * Makes a copy of a #GdkRGBA structure, the result must be freed
+ * through gdk_rgba_free().
+ *
+ * Returns: A newly allocated #GdkRGBA
+ **/
+GdkRGBA *
+gdk_rgba_copy (GdkRGBA *rgba)
+{
+  GdkRGBA *copy;
+
+  copy = g_slice_new (GdkRGBA);
+  copy->red = rgba->red;
+  copy->green = rgba->green;
+  copy->blue = rgba->blue;
+  copy->alpha = rgba->alpha;
+
+  return copy;
+}
+
+/**
+ * gdk_rgba_free:
+ * @rgba: a #GdkRGBA
+ *
+ * Frees a #GdkRGBA struct created with gdk_rgba_copy()
+ **/
+void
+gdk_rgba_free (GdkRGBA *rgba)
+{
+  g_slice_free (GdkRGBA, rgba);
+}
+
+/**
+ * gdk_rgba_parse:
+ * @spec: the string specifying the color
+ * @rgba: the #GdkRGBA struct to fill in
+ *
+ * Parses a textual representation of a color, filling in
+ * the <structfield>red</structfield>, <structfield>green</structfield>,
+ * <structfield>blue</structfield> and <structfield>alpha</structfield>
+ * fields of the @rgba struct.
+ *
+ * The string can be either one of:
+ * <itemizedlist>
+ * <listitem>
+ * A standard name (Taken from the X11 rgb.txt file).
+ * </listitem>
+ * <listitem>
+ * A hex value in the form '#rgb' '#rrggbb' '#rrrgggbbb' or '#rrrrggggbbbb'
+ * </listitem>
+ * <listitem>
+ * A RGB color in the form 'rgb(r,g,b)' (In this case the color will
+ * have full opacity)
+ * </listitem>
+ * <listitem>
+ * A RGBA color in the form 'rgba(r,g,b,a)'
+ * </listitem>
+ * </itemizedlist>
+ *
+ * Where 'r', 'g', 'b' and 'a' are respectively the red, green, blue and
+ * alpha color values, parsed in the last 2 cases as double numbers in
+ * the range [0..1], any other value out of that range will be clamped.
+ *
+ * Returns: %TRUE if the parsing succeeded
+ **/
+gboolean
+gdk_rgba_parse (const gchar *spec,
+                GdkRGBA     *rgba)
+{
+  gboolean has_alpha;
+  gdouble r, g, b, a;
+  gchar *str = (gchar *) spec;
+
+#define SKIP_WHITESPACES(s) while (*(s) == ' ') (s)++;
+
+  if (strncmp (str, "rgba", 4) == 0)
+    {
+      has_alpha = TRUE;
+      str += 4;
+    }
+  else if (strncmp (str, "rgb", 3) == 0)
+    {
+      has_alpha = FALSE;
+      a = 1;
+      str += 3;
+    }
+  else
+    {
+      PangoColor pango_color;
+
+      /* Resort on PangoColor for rgb.txt color
+       * map and '#' prefixed colors */
+      if (pango_color_parse (&pango_color, str))
+        {
+          if (rgba)
+            {
+              rgba->red = pango_color.red / 65535.;
+              rgba->green = pango_color.green / 65535.;
+              rgba->blue = pango_color.blue / 65535.;
+              rgba->alpha = 1;
+            }
+
+          return TRUE;
+        }
+      else
+        return FALSE;
+    }
+
+  SKIP_WHITESPACES (str);
+
+  if (*str != '(')
+    return FALSE;
+
+  str++;
+
+  /* Parse red */
+  SKIP_WHITESPACES (str);
+  r = g_ascii_strtod (str, &str);
+  SKIP_WHITESPACES (str);
+
+  if (*str != ',')
+    return FALSE;
+
+  str++;
+
+  /* Parse green */
+  SKIP_WHITESPACES (str);
+  g = g_ascii_strtod (str, &str);
+  SKIP_WHITESPACES (str);
+
+  if (*str != ',')
+    return FALSE;
+
+  str++;
+
+  /* Parse blue */
+  SKIP_WHITESPACES (str);
+  b = g_ascii_strtod (str, &str);
+  SKIP_WHITESPACES (str);
+
+  if (has_alpha)
+    {
+      if (*str != ',')
+        return FALSE;
+
+      str++;
+
+      SKIP_WHITESPACES (str);
+      a = g_ascii_strtod (str, &str);
+      SKIP_WHITESPACES (str);
+    }
+
+  if (*str != ')')
+    return FALSE;
+
+#undef SKIP_WHITESPACES
+
+  if (rgba)
+    {
+      rgba->red = CLAMP (r, 0, 1);
+      rgba->green = CLAMP (g, 0, 1);
+      rgba->blue = CLAMP (b, 0, 1);
+      rgba->alpha = CLAMP (a, 0, 1);
+    }
+
+  return TRUE;
+}
+
+/**
+ * gdk_rgba_hash:
+ * @p: a #GdkRGBA pointer.
+ *
+ * A hash function suitable for using for a hash
+ * table that stores #GdkRGBA<!-- -->s.
+ *
+ * Return value: The hash function applied to @p
+ **/
+guint
+gdk_rgba_hash (gconstpointer p)
+{
+  const GdkRGBA *rgba = p;
+
+  return ((guint) (rgba->red * 65535) +
+         ((guint) (rgba->green * 65535) << 11) +
+         ((guint) (rgba->blue * 65535) << 22) +
+         ((guint) (rgba->alpha * 65535) >> 6));
+}
+
+/**
+ * gdk_rgba_equal:
+ * @p1: a #GdkRGBA pointer.
+ * @p2: another #GdkRGBA pointer.
+ *
+ * Compares two RGBA colors.
+ *
+ * Return value: %TRUE if the two colors compare equal
+ **/
+gboolean
+gdk_rgba_equal (gconstpointer p1,
+                gconstpointer p2)
+{
+  const GdkRGBA *rgba1, *rgba2;
+
+  rgba1 = p1;
+  rgba2 = p2;
+
+  if (rgba1->red == rgba2->red &&
+      rgba1->green == rgba2->green &&
+      rgba1->blue == rgba2->blue &&
+      rgba1->alpha == rgba2->alpha)
+    return TRUE;
+
+  return FALSE;
+}
+
+/**
+ * gdk_rgba_to_string:
+ * @rgba: a #GdkRGBA
+ *
+ * Returns a textual specification of @rgba in the form
+ * <literal>rgba (r, g, b, a)</literal>, where 'r', 'g',
+ * 'b' and 'a' represent the red, green, blue and alpha
+ * values respectively.
+ *
+ * Returns: A newly allocated text string
+ **/
+gchar *
+gdk_rgba_to_string (GdkRGBA *rgba)
+{
+  return g_strdup_printf ("rgba(%f,%f,%f,%f)",
+                          CLAMP (rgba->red, 0, 1),
+                          CLAMP (rgba->green, 0, 1),
+                          CLAMP (rgba->blue, 0, 1),
+                          CLAMP (rgba->alpha, 0, 1));
+}
diff --git a/gdk/gdkrgba.h b/gdk/gdkrgba.h
new file mode 100644 (file)
index 0000000..7b50630
--- /dev/null
@@ -0,0 +1,65 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
+#error "Only <gdk/gdk.h> can be included directly."
+#endif
+
+#ifndef __GDK_RGBA_H__
+#define __GDK_RGBA_H__
+
+#include <gdk/gdktypes.h>
+
+G_BEGIN_DECLS
+
+struct _GdkRGBA
+{
+  gdouble red;
+  gdouble green;
+  gdouble blue;
+  gdouble alpha;
+};
+
+#define GDK_TYPE_RGBA (gdk_rgba_get_type ())
+
+GdkRGBA * gdk_rgba_copy (GdkRGBA *rgba);
+void      gdk_rgba_free (GdkRGBA *rgba);
+
+gboolean  gdk_rgba_parse (const gchar *spec,
+                          GdkRGBA     *rgba);
+
+guint     gdk_rgba_hash  (gconstpointer p);
+gboolean  gdk_rgba_equal (gconstpointer p1,
+                          gconstpointer p2);
+
+gchar *   gdk_rgba_to_string (GdkRGBA *rgba);
+
+GType     gdk_rgba_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif /* __GDK_RGBA_H__ */
index aaa17b59e1e237c80da02fdb264905160f39a576..53937d8ca6fb70da5e05d653aebcea631b1b61fc 100644 (file)
@@ -96,6 +96,7 @@ typedef guint32 GdkNativeWindow;
 /* Forward declarations of commonly used types
  */
 typedef struct _GdkColor             GdkColor;
+typedef struct _GdkRGBA               GdkRGBA;
 typedef struct _GdkCursor            GdkCursor;
 typedef struct _GdkVisual             GdkVisual;